package io.gitee.zhangbinhub.acp.boot

import com.fasterxml.jackson.dataformat.xml.XmlMapper
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator
import io.gitee.zhangbinhub.acp.boot.component.AcpBootGlobalFilter
import io.gitee.zhangbinhub.acp.boot.component.AcpTimerTaskSchedulerCtrl
import io.gitee.zhangbinhub.acp.boot.component.SystemControl
import io.gitee.zhangbinhub.acp.boot.conf.AcpCorsConfiguration
import io.gitee.zhangbinhub.acp.boot.constant.AcpCoreConstant
import io.gitee.zhangbinhub.acp.boot.exceptions.AcpDefaultWebExceptionHandler
import io.gitee.zhangbinhub.acp.boot.exceptions.AcpWebExceptionHandler
import io.gitee.zhangbinhub.acp.boot.init.SystemInitialization
import io.gitee.zhangbinhub.acp.boot.listener.AcpListener
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.boot.tools.ServerTools
import org.noear.solon.annotation.Bean
import org.noear.solon.annotation.Configuration
import org.noear.solon.annotation.Import
import org.noear.solon.annotation.Inject
import org.noear.solon.serialization.jackson.xml.JacksonXmlStringSerializer

@Configuration
@Import(AcpCorsConfiguration::class)
class AcpBootComponentAutoConfiguration {
    @Bean
    fun serverTools(): ServerTools = ServerTools()

    @Bean
    fun acpTimerTaskSchedulerCtrl(
        @Inject logAdapter: LogAdapter,
    ): AcpTimerTaskSchedulerCtrl = AcpTimerTaskSchedulerCtrl(logAdapter)

    @Bean
    fun systemControl(
        @Inject logAdapter: LogAdapter,
        @Inject acpListenerList: MutableList<AcpListener>,
        @Inject acpTimerTaskSchedulerCtrl: AcpTimerTaskSchedulerCtrl
    ): SystemControl = SystemControl(logAdapter, acpListenerList, acpTimerTaskSchedulerCtrl)

    @Bean(index = Int.MIN_VALUE)
    fun systemInitialization(
        @Inject logAdapter: LogAdapter,
        @Inject serverTools: ServerTools,
        @Inject systemControl: SystemControl
    ): SystemInitialization = SystemInitialization(logAdapter, serverTools, systemControl)

    @Bean(index = Int.MAX_VALUE)
    fun defaultWebExceptionHandler(): AcpDefaultWebExceptionHandler = AcpDefaultWebExceptionHandler()

    @Bean(index = AcpCoreConstant.CORS_FILTER_ORDER - 1)
    fun acpBootGlobalFilter(
        @Inject logAdapter: LogAdapter,
        @Inject acpWebExceptionHandler: MutableList<AcpWebExceptionHandler>
    ): AcpBootGlobalFilter = AcpBootGlobalFilter(logAdapter, acpWebExceptionHandler)

    @Bean
    fun xmlMapper(@Inject serializer: JacksonXmlStringSerializer): XmlMapper =
        serializer.serializeConfig.mapper.apply {
            this.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION)
            this.setDefaultTyping(null)
        }
}